﻿using AutoMapper;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using Ross.EntityFramework;
using Ross.EntityFramework.Model;
using Ross.Service.Dto;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace Ross.Service
{
    public class BSCReports_DPService : BaseService, IDisposable
    {
        private TranDbContext dbContext;
        public IRepository<Targets, int> repository_T;
        public IRepository<History, int> repository_H;
        public IRepository<Users, int> userresp;
        private ResultDto<List<Dto.BSCReports_Dp>> results = new ResultDto<List<Dto.BSCReports_Dp>>();
        private TargetService targetService;
        public BSCReports_DPService(string nameOrConnectionString)
        {
            results.datas = new List<BSCReports_Dp>();
            dbContext = new TranDbContext(nameOrConnectionString);
            repository_T = new Repository<Targets, int>(dbContext);
            repository_H = new Repository<History, int>(dbContext);
            userresp = new Repository<Users, int>(dbContext);
            targetService = new TargetService(nameOrConnectionString);
        }

        public void Dispose()
        {
            dbContext.Dispose();
        }

        public ResultDto<List<Dto.BSCReports_Dp>> GetTreeList(string version = "", string name = "", bool approvalStatus = true)
        {
            ResultDto<List<Dto.BSCReports_Dp>> result = new ResultDto<List<Dto.BSCReports_Dp>>();
            List<Dto.BSCReports_Dp> trees = new List<BSCReports_Dp>();
            List<Dto.BSCReports_Dp> zhanlue = new List<BSCReports_Dp>();
            if (string.IsNullOrEmpty(name))
            {
                name = username;
            }
            var user = userresp.GetAllList(o => o.UserName == name || o.EmpID == name).FirstOrDefault();
            string[] adepts = user.AuthorizedDepartment.Split(',');
            var lists_t = new List<Targets>();
            var lists_h = new List<History>();
            //Expression<Func<Targets, bool>> expression = o => o.ApprovalStatus == "已审核" && adepts.Contains(o.Department) && o.Depth == 1;
            if (!string.IsNullOrEmpty(version))
            {
                var lists = repository_H.GetAllList(o => o.Version == version).ToList();
                var resp = GetTargetsTree(lists);
                var tree = resp.Where(o => o.TargetName == year.ToString() && adepts.Contains(o.Department)).ToList();
                if (tree.Count > 0)
                    result.datas = tree;
                else
                    result.message = $"未查询到{year}年数据";
            }
            else 
            {
                var tree = new List<BSCReports_Dp>();
                if (approvalStatus)
                {
                    lists_t = repository_T.GetAllList().ToList();
                    var resp = GetTargetsTree(lists_t);
                    tree = resp.Where(o => o.TargetName == year.ToString() && adepts.Contains(o.Department)).ToList();

                }
                else
                {
                    lists_t = repository_T.GetAllList().ToList();
                    var resp = GetTargetsTree(lists_t);
                    tree = resp.Where(o => o.TargetName == year.ToString() && adepts.Contains(o.Department)).ToList();
                }
                if (tree.Count > 0)
                    result.datas = tree;
                else
                    result.message = $"未查询到{year}年数据";
            }
            return result;
        }

        /// <summary>
        /// 创建目标任务树
        /// </summary>
        /// <param name="datas"></param>
        /// <param name="parentid"></param>
        /// <returns></returns>
        private List<Dto.BSCReports_Dp> GetTargetsTree(List<Targets> datas, int parentid = -1)
        {
            List<Dto.BSCReports_Dp> result = new List<Dto.BSCReports_Dp>();
            var lists = datas.Where(o => o.ParentTargetID == parentid).ToList();
            foreach (var item in lists)
            {
                Dto.BSCReports_Dp obj = new Dto.BSCReports_Dp();
                obj = Mapper.Map<Dto.BSCReports_Dp>(item);
                var childrens = datas.Where(o => o.ParentTargetID == item.ID).ToList();
                if (childrens.Count > 0)
                {
                    obj.Child = GetTargetsTree(datas, item.ID);
                }
                result.Add(obj);
            }
            return result;
        }
        /// <summary>
        /// 创建目标任务树
        /// </summary>
        /// <param name="datas"></param>
        /// <param name="parentid"></param>
        /// <returns></returns>
        private List<Dto.BSCReports_Dp> GetTargetsTree(List<History> datas, int parentid = -1)
        {
            List<Dto.BSCReports_Dp> result = new List<Dto.BSCReports_Dp>();
            var lists = datas.Where(o => o.ParentTargetID == parentid).ToList();
            foreach (var item in lists)
            {
                Dto.BSCReports_Dp obj = new Dto.BSCReports_Dp();
                obj = Mapper.Map<Dto.BSCReports_Dp>(item);
                var childrens = datas.Where(o => o.ParentTargetID == item.SourceID).ToList();
                if (childrens.Count > 0)
                {
                    obj.Child = GetTargetsTree(datas, item.SourceID);
                }
                result.Add(obj);
            }
            return result;
        }
        /// <summary>
        /// 部门报表
        /// </summary>
        /// <returns></returns>
        public ResultDto<List<BSCReports_DpOut>> GetReports(string version = "", string name = "", bool approvalStatus = true)
        {
            ResultDto<List<BSCReports_DpOut>> result = new ResultDto<List<BSCReports_DpOut>>();
            try
            {
                List<Dto.BSCReports_Dp> datas = new List<BSCReports_Dp>();
                List<BSCReports_DpOut> lists = new List<BSCReports_DpOut>();
                datas = GetTreeList(version, name, approvalStatus).datas;
                var depts = targetService.GetDeptAsync();
                if (datas != null)
                {
                    foreach (var niandu in datas)
                    {
                        if (niandu.Child != null)
                        {
                            foreach (var jiaodu in niandu.Child)
                            {
                                if (jiaodu.Child != null)
                                {
                                    foreach (var zhanlue in jiaodu.Child)
                                    {

                                        
                                        if (zhanlue.Child != null)
                                        {
                                            foreach (var bumen in zhanlue.Child)
                                            {
                                                BSCReports_DpOut bSCReports_DpOut = new BSCReports_DpOut();
                                                bSCReports_DpOut.Classification = jiaodu.TargetName;
                                                bSCReports_DpOut.TargetName = zhanlue.TargetName;
                                                //缺少审核状态
                                                bSCReports_DpOut.ApprovalStatus = bumen.ApprovalStatus;
                                                bSCReports_DpOut.Lock = bumen.Lock;
                                                bSCReports_DpOut.DepartmentTarget = bumen.TargetName;
                                                bSCReports_DpOut.ID = bumen.ID;
                                                if (bumen.Child != null)
                                                {
                                                    foreach (var Child1 in bumen.Child)
                                                    {
                                                        bSCReports_DpOut.StartingTime1 = Child1.StartingTime;
                                                        bSCReports_DpOut.ActualCompletionTime1 = Child1.ActualCompletionTime;
                                                        bSCReports_DpOut.PlannedCompletionTime1 = Child1.PlannedCompletionTime;
                                                        bSCReports_DpOut.Responsible1 = Child1.Responsible;
                                                        bSCReports_DpOut.AssessmentCriteria1 = Child1.AssessmentCriteria;
                                                        bSCReports_DpOut.content1 = Child1.TargetName;
                                                        if (Child1.Child!=null)
                                                        {
                                                            foreach (var Child2 in Child1.Child)
                                                            {
                                                                bSCReports_DpOut.StartingTime2 = Child2.StartingTime;
                                                                bSCReports_DpOut.ActualCompletionTime2 = Child1.ActualCompletionTime;
                                                                bSCReports_DpOut.PlannedCompletionTime2 = Child2.PlannedCompletionTime;
                                                                bSCReports_DpOut.Responsible2 = Child2.Responsible;
                                                                bSCReports_DpOut.AssessmentCriteria2 = Child2.AssessmentCriteria;
                                                                bSCReports_DpOut.content2 = Child2.TargetName;
                                                                if (Child2.Child != null)
                                                                {
                                                                    foreach (var Child3 in Child2.Child)
                                                                    {
                                                                        bSCReports_DpOut.StartingTime3 = Child3.StartingTime;
                                                                        bSCReports_DpOut.ActualCompletionTime3 = Child1.ActualCompletionTime;
                                                                        bSCReports_DpOut.PlannedCompletionTime3 = Child3.PlannedCompletionTime;
                                                                        bSCReports_DpOut.Responsible3 = Child3.Responsible;
                                                                        bSCReports_DpOut.AssessmentCriteria3 = Child3.AssessmentCriteria;
                                                                        bSCReports_DpOut.content3 = Child3.TargetName;
                                                                        bSCReports_DpOut.Budget = (Child3.Budget1 + Child3.Budget2 + Child3.Budget3).ToString();
                                                                    }
                                                                }
                                                                else
                                                                    bSCReports_DpOut.Budget = (Child2.Budget1 + Child2.Budget2 + Child2.Budget3).ToString();
                                                            }
                                                        }
                                                        else
                                                            bSCReports_DpOut.Budget = (Child1.Budget1 + Child1.Budget2 + Child1.Budget3).ToString();
                                                    }
                                                }
                                                else
                                                    bSCReports_DpOut.Budget = (bumen.Budget1 + bumen.Budget2 + bumen.Budget3).ToString();
                                                bSCReports_DpOut.AssessmentMethod = bumen.AssessmentMethod;
                                                bSCReports_DpOut.Statistician = bumen.Statistician;
                                                if (!string.IsNullOrEmpty(bumen.ResourceSupport))
                                                    bSCReports_DpOut.ResourceSupport = depts.Where(o => o.DepartmentID == bumen.ResourceSupport).ToList()[0].DepartmentName;
                                                bSCReports_DpOut.Remarks = bumen.Remarks;
                                                lists.Add(bSCReports_DpOut);
                                            }
                                        }

                                        
                                    }
                                }
                            }
                        }
                    }
                }
                if (approvalStatus)
                {
                    var newlists = lists.Where(o => o.ApprovalStatus == "已审核" && o.Lock == true).ToList();
                    result.datas = newlists;
                }
                else
                {
                    var newlists = lists.Where(o => o.ApprovalStatus == "审核中" && o.Lock == true).ToList();
                    result.datas = newlists;
                }
            }
            catch (Exception e)
            {
                result.status = 500;
                result.message = e.Message;
            }
            return result;
        }

        /// <summary>
        /// 导出部门级报表
        /// </summary>
        /// <returns></returns>
        public FileResult ExportExcel_Dp(string version = "", string name = "", bool approvalStatus = true)
        {
            //ResultDto<FileResult> result = new ResultDto<FileResult>();
            try
            {
                HSSFWorkbook book = new HSSFWorkbook();
                ISheet sheet1 = book.CreateSheet("Sheet1");
                //设置列宽
                for (int i = 0; i < 20; i++)
                    sheet1.SetColumnWidth(i, 3000);
                //标题设置
                IRow row0 = sheet1.CreateRow(0);
                row0.HeightInPoints = 30;
                IFont fontTitle = book.CreateFont();
                fontTitle.FontHeightInPoints = 12;
                fontTitle.Boldweight = (short)FontBoldWeight.Bold;
                //设置单元格边框
                ICellStyle styleTiltle = book.CreateCellStyle();
                styleTiltle.Alignment = HorizontalAlignment.Center;
                styleTiltle.SetFont(fontTitle);
                styleTiltle.VerticalAlignment = VerticalAlignment.Center;
                IFont fontContent = book.CreateFont();
                fontContent.FontHeightInPoints = 12;
                ICellStyle styleContent = book.CreateCellStyle();
                styleContent.Alignment = HorizontalAlignment.Center;
                styleContent.SetFont(fontContent);
                styleContent.VerticalAlignment = VerticalAlignment.Center;
                string currxzq = "BSC报表-部门级";
                row0.CreateCell(0).SetCellValue(currxzq);
                sheet1.AddMergedRegion(new CellRangeAddress(0, 0, 0, 20));
                row0.GetCell(0).CellStyle = styleTiltle;

                //设置内容单元格
                string[] colums = ("分类|战略目标|部门目标|措施分解|考核方式|统计人|资源支持|预算|备注").Split('|');
                IRow row1 = sheet1.CreateRow(1);
                for (int i = 0; i < colums.Length; i++)
                {
                    if (i < 3)
                    {
                        row1.CreateCell(i).SetCellValue(colums[i]);
                        sheet1.AddMergedRegion(new CellRangeAddress(1, 3, i, i));
                        row1.GetCell(i).CellStyle = styleContent;
                    }
                    if (i==3)
                    {
                        row1.CreateCell(i).SetCellValue(colums[i]);
                        sheet1.AddMergedRegion(new CellRangeAddress(1, 1, 3, 14));
                        row1.GetCell(i).CellStyle = styleContent;
                    }
                    if (i>=4)
                    {
                        row1.CreateCell(i+11).SetCellValue(colums[i]);
                        sheet1.AddMergedRegion(new CellRangeAddress(1, 3, i + 11, i + 11));
                        row1.GetCell(i+11).CellStyle = styleContent;
                    }


                }
                IRow row2 = sheet1.CreateRow(2);
                string[] colums2 = ("一级计划|二级计划|三级计划").Split('|');
                for (int i = 0; i < colums2.Length; i++)
                {
                    row2.CreateCell(3 + i * 4).SetCellValue(colums2[i]);
                    sheet1.AddMergedRegion(new CellRangeAddress(2, 2, 3 + i * 4, 6 + i * 4));
                    row2.GetCell(3 + i * 4).CellStyle = styleContent;
                }
                IRow row3 = sheet1.CreateRow(3);
                string[] colums3 = ("内容|责任人|开始时间|结束时间|内容|责任人|开始时间|结束时间|内容|责任人|开始时间|结束时间").Split('|');
                for (int i = 0; i < colums3.Length; i++)
                {
                    row3.CreateCell(3 + i).SetCellValue(colums3[i]);
                    sheet1.AddMergedRegion(new CellRangeAddress(3, 3, 3 + i, 3 + i));
                    row3.GetCell(3 + i).CellStyle = styleContent;
                }
                //填写数据
                ResultDto<List<BSCReports_DpOut>> list = new ResultDto<List<BSCReports_DpOut>>();
                list = GetReports(version, name, approvalStatus);
                List<BSCReports_DpOut> datas = new List<BSCReports_DpOut>();
                datas = list.datas;
                //ICellStyle Datestyle = book.CreateCellStyle();
                //IDataFormat dataformat = book.CreateDataFormat();
                //Datestyle.DataFormat = dataformat.GetFormat("yyyy年MM月dd日");
                for (int i = 0; i < datas.Count; i++)
                {
                    IRow row4 = sheet1.CreateRow(i + 4);
                    row4.CreateCell(0).SetCellValue(list.datas[i].Classification);
                    row4.CreateCell(1).SetCellValue(list.datas[i].TargetName);
                    row4.CreateCell(2).SetCellValue(list.datas[i].DepartmentTarget);
                    row4.CreateCell(3).SetCellValue(list.datas[i].content1);
                    row4.CreateCell(4).SetCellValue(list.datas[i].Responsible1);
                    if (list.datas[i].StartingTime1.ToString("yyyy-MM-dd HH:mm:ss") == "0001-01-01 00:00:00")
                        row4.CreateCell(5).SetCellValue("");
                    else
                        row4.CreateCell(5).SetCellValue(list.datas[i].StartingTime1.ToString("yyyy-MM-dd HH:mm:ss"));
                    //row4.GetCell(5).CellStyle = Datestyle;
                    if (list.datas[i].ActualCompletionTime1.ToString("yyyy-MM-dd HH:mm:ss") == "0001-01-01 00:00:00")
                        row4.CreateCell(6).SetCellValue("");
                    else
                        row4.CreateCell(6).SetCellValue(list.datas[i].ActualCompletionTime1.ToString("yyyy-MM-dd HH:mm:ss"));
                    //row4.GetCell(6).CellStyle = Datestyle;
                    row4.CreateCell(7).SetCellValue(list.datas[i].content2);
                    row4.CreateCell(8).SetCellValue(list.datas[i].Responsible2);
                    if (list.datas[i].StartingTime2.ToString("yyyy-MM-dd HH:mm:ss") == "0001-01-01 00:00:00")
                        row4.CreateCell(9).SetCellValue("");
                    else
                        row4.CreateCell(9).SetCellValue(list.datas[i].StartingTime2.ToString("yyyy-MM-dd HH:mm:ss"));
                    //row4.GetCell(9).CellStyle = Datestyle;
                    if (list.datas[i].ActualCompletionTime2.ToString("yyyy-MM-dd HH:mm:ss") == "0001-01-01 00:00:00")
                        row4.CreateCell(10).SetCellValue("");
                    else
                        row4.CreateCell(10).SetCellValue(list.datas[i].ActualCompletionTime2.ToString("yyyy-MM-dd HH:mm:ss"));
                    //row4.GetCell(10).CellStyle = Datestyle;
                    row4.CreateCell(11).SetCellValue(list.datas[i].content3);
                    row4.CreateCell(12).SetCellValue(list.datas[i].Responsible3);
                    if (list.datas[i].StartingTime3.ToString("yyyy-MM-dd HH:mm:ss") == "0001-01-01 00:00:00")
                        row4.CreateCell(13).SetCellValue("");
                    else
                        row4.CreateCell(13).SetCellValue(list.datas[i].StartingTime3.ToString("yyyy-MM-dd HH:mm:ss"));
                    //row4.GetCell(13).CellStyle = Datestyle;
                    if (list.datas[i].ActualCompletionTime3.ToString("yyyy-MM-dd HH:mm:ss") == "0001-01-01 00:00:00")
                        row4.CreateCell(14).SetCellValue("");
                    else
                        row4.CreateCell(14).SetCellValue(list.datas[i].ActualCompletionTime3.ToString("yyyy-MM-dd HH:mm:ss"));
                    //row4.GetCell(14).CellStyle = Datestyle;
                    row4.CreateCell(15).SetCellValue(list.datas[i].AssessmentMethod);
                    row4.CreateCell(16).SetCellValue(list.datas[i].Statistician);
                    row4.CreateCell(17).SetCellValue(list.datas[i].ResourceSupport);

                    row4.CreateCell(18).SetCellValue(list.datas[i].Budget);
                    row4.CreateCell(19).SetCellValue(list.datas[i].Remarks);
                }
                //返回文件流至前台
                MemoryStream ms = new MemoryStream();
                book.Write(ms);
                ms.Seek(0, SeekOrigin.Begin);
                FileStreamResult file = new FileStreamResult(ms, "application/vnd.ms-excel");
                file.FileDownloadName = "BSC部门报表" + DateTime.Now.ToString("yyyyMMddhhmmss") + ".xls";
                return file;
            }
            catch (Exception e)
            {
                //result.status = 500;
                //result.message = e.Message;
                //throw;
            }
            return null;
        }

        /// <summary>
        /// 更新状态
        /// </summary>
        /// <param name="id"></param>
        /// <param name="ApprovalStatus"></param>
        /// <returns></returns>
        public ResultDto<bool> UpdateApprovalStatus(int id, string ApprovalStatus)
        {
            ResultDto<bool> result = new ResultDto<bool>();
            try
            {
                var bumen = repository_T.Get(id);
                bumen.ApprovalStatus = ApprovalStatus;
                repository_T.Update(bumen);
                List<int> idss = new List<int>();
                idss = ids(bumen, idss);
                foreach (var item in idss)
                {
                    var child = repository_T.Get(item);
                    child.ApprovalStatus = ApprovalStatus;
                    repository_T.Update(child);
                }
                result.datas = true;
                return result;
            }
            catch (Exception)
            {
                result.datas = false;
            }
            return result;
        }

        List<int> ids(Targets targets, List<int> idss)
        {
            var child = repository_T.GetAllList(o => o.ParentTargetID == targets.ID);
            if(child!=null)
            {
                foreach (var item in child)
                {
                    idss.Add(item.ID);
                    ids(item, idss);
                }
            }
            return idss;
        }

        public ResultDto<List<string>> GetVersion()
        {
            List<string> ver = new List<string>();
            ResultDto<List<string>> result = new ResultDto<List<string>>();
            try
            {
                var list = repository_H.GetAllList(o => o.ParentTargetID == -1 && o.TargetName == year.ToString());
                foreach (var item in list)
                {
                    ver.Add(item.Version);
                }
                result.datas = ver;
                return result;
            }
            catch (Exception e)
            {
                result.status = 500;
                result.message = e.Message;
            }
            return result;
        }
    }
}
